﻿using System;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using NUnit.Framework.SyntaxHelpers;
using Yaml.Presentation.Parsing;
using Yaml.Presentation.Tokens;


namespace Yaml.Tests.Presentation.ScannerTests {
    [TestFixture]
    public class Tags {
        [Test]
        public void VerbatimTag() {
            Scanner s = Helper.CreateScanner("!<tag:yaml.org,2002>\n!<!foobar>");
            Token t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamStartToken)));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='verbatim' handle='' suffix='tag:yaml.org,2002' start={0:0,0} end={20:0,20}>"), "<URI> is a valid verbatim tag name");
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='verbatim' handle='' suffix='!foobar' start={21:1,0} end={31:1,10}>"), "<!localtag> is a valid verbatim tag name");
            t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamEndToken)));
        }

        [Test, ExpectedException(typeof(Yaml.Presentation.ScannerException))]
        public void InvalidURIVerbatimTag() {
            Scanner s = Helper.CreateScanner("!<$:?>");
            Token t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamStartToken)));
            t = s.GetToken();
        }

        [Test, ExpectedException(typeof(Yaml.Presentation.ScannerException))]
        public void InvalidLocalVerbatimTag() {
            Scanner s = Helper.CreateScanner("!<!>");
            Token t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamStartToken)));
            t = s.GetToken();
        }

        [Test]
        public void NonSpecificTag() {
            Scanner s = Helper.CreateScanner("!\n! ");
            Token t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamStartToken)));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='nonspecific' handle='!' suffix='' start={0:0,0} end={1:0,1}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='nonspecific' handle='!' suffix='' start={2:1,0} end={3:1,1}>"), "<!localtag> is a valid verbatim tag name");
            t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamEndToken)));
        }

        [Test]
        public void PrimaryTag() {
            Scanner s = Helper.CreateScanner("!foo\n!bar ");
            Token t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamStartToken)));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='primaryshorthand' handle='!' suffix='foo' start={0:0,0} end={4:0,5}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagToken type='primaryshorthand' handle='!' suffix='bar' start={6:1,0} end={10:1,4}>"));
            t = s.GetToken();
            Assert.That(t, Is.InstanceOfType(typeof(StreamEndToken)));
        }
    }
}
